'use client';

import { useState, useRef } from 'react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { CopyButton, CodeCopyWrapper } from '@/components/ui/copy-button';
import {
  Download,
  Play,
  Eye,
  EyeOff,
  Maximize2,
  Minimize2,
} from 'lucide-react';

interface CodeBlockProps {
  code: string;
  language?: string;
  filename?: string;
  title?: string;
  showLineNumbers?: boolean;
  highlightLines?: number[];
  maxHeight?: string;
  allowCopy?: boolean;
  allowDownload?: boolean;
  allowRun?: boolean;
  className?: string;
}

/**
 * 代码块组件
 * 支持语法高亮、代码复制、下载等功能
 */
export function CodeBlock({
  code,
  language = 'text',
  filename,
  title,
  showLineNumbers = true,
  highlightLines = [],
  maxHeight = '400px',
  allowCopy = true,
  allowDownload = false,
  allowRun = false,
  className,
}: CodeBlockProps) {
  const [isExpanded, setIsExpanded] = useState(false);
  const [showPreview, setShowPreview] = useState(false);
  const codeRef = useRef<HTMLPreElement>(null);

  // 语言映射
  const languageMap: Record<string, string> = {
    cangjie: 'cj',
    cj: 'cangjie',
    javascript: 'js',
    typescript: 'ts',
    python: 'py',
    bash: 'shell',
    shell: 'bash',
  };

  const displayLanguage = languageMap[language] || language;

  /**
   * 下载代码文件
   */
  const downloadCode = () => {
    const extension = getFileExtension(language);
    const fileName = filename || `code.${extension}`;
    const blob = new Blob([code], { type: 'text/plain' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = fileName;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  };

  /**
   * 运行代码（模拟）
   */
  const runCode = () => {
    // 这里可以集成代码执行服务
    console.log('Running code:', code);
    alert('代码执行功能正在开发中...');
  };

  /**
   * 获取文件扩展名
   */
  const getFileExtension = (lang: string): string => {
    const extensions: Record<string, string> = {
      cangjie: 'cj',
      cj: 'cj',
      javascript: 'js',
      typescript: 'ts',
      python: 'py',
      java: 'java',
      cpp: 'cpp',
      c: 'c',
      go: 'go',
      rust: 'rs',
      bash: 'sh',
      shell: 'sh',
      json: 'json',
      yaml: 'yml',
      xml: 'xml',
      html: 'html',
      css: 'css',
      sql: 'sql',
    };
    return extensions[lang] || 'txt';
  };

  /**
   * 获取语言颜色
   */
  const getLanguageColor = (lang: string): string => {
    const colors: Record<string, string> = {
      cangjie:
        'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300',
      cj: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-300',
      javascript:
        'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-300',
      typescript:
        'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-300',
      python:
        'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-300',
      java: 'bg-orange-100 text-orange-800 dark:bg-orange-900 dark:text-orange-300',
      cpp: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900 dark:text-indigo-300',
      go: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900 dark:text-cyan-300',
      rust: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-300',
      bash: 'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300',
      json: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900 dark:text-emerald-300',
    };
    return (
      colors[lang] ||
      'bg-gray-100 text-gray-800 dark:bg-gray-900 dark:text-gray-300'
    );
  };

  /**
   * 语法高亮（简化版）
   */
  const highlightSyntax = (code: string, lang: string): string => {
    if (lang === 'cangjie' || lang === 'cj') {
      return highlightCangjie(code);
    }

    // 其他语言的基本高亮
    return code
      .replace(
        /\b(function|class|const|let|var|if|else|for|while|return|import|export)\b/g,
        '<span class="text-blue-600 dark:text-blue-400 font-semibold">$1</span>'
      )
      .replace(
        /(\/\/.*$)/gm,
        '<span class="text-gray-500 dark:text-gray-400 italic">$1</span>'
      )
      .replace(
        /("[^"]*"|'[^']*')/g,
        '<span class="text-green-600 dark:text-green-400">$1</span>'
      )
      .replace(
        /\b(\d+)\b/g,
        '<span class="text-orange-600 dark:text-orange-400">$1</span>'
      );
  };

  /**
   * 仓颉语言语法高亮
   */
  const highlightCangjie = (code: string): string => {
    return (
      code
        // 关键字
        .replace(
          /\b(class|struct|enum|interface|func|let|var|const|if|else|match|case|for|while|do|return|import|package|public|private|protected|static|override|abstract|final|async|await|try|catch|throw|extends|implements)\b/g,
          '<span class="text-blue-600 dark:text-blue-400 font-semibold">$1</span>'
        )
        // 类型
        .replace(
          /\b(Int32|Int64|Float32|Float64|String|Bool|Array|Map|Option|Result|Unit|Actor|ActorRef|Message)\b/g,
          '<span class="text-purple-600 dark:text-purple-400 font-medium">$1</span>'
        )
        // 注释
        .replace(
          /(#.*$)/gm,
          '<span class="text-gray-500 dark:text-gray-400 italic">$1</span>'
        )
        .replace(
          /(\/\*[\s\S]*?\*\/)/g,
          '<span class="text-gray-500 dark:text-gray-400 italic">$1</span>'
        )
        // 字符串
        .replace(
          /("[^"]*"|'[^']*')/g,
          '<span class="text-green-600 dark:text-green-400">$1</span>'
        )
        // 数字
        .replace(
          /\b(\d+(?:\.\d+)?)\b/g,
          '<span class="text-orange-600 dark:text-orange-400">$1</span>'
        )
        // 操作符
        .replace(
          /([+\-*/%=<>!&|]+)/g,
          '<span class="text-red-600 dark:text-red-400">$1</span>'
        )
    );
  };

  const lines = code.split('\n');
  const highlightedCode = highlightSyntax(code, language);
  const highlightedLines = highlightedCode.split('\n');

  return (
    <div
      className={cn(
        'relative group border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden bg-gray-50 dark:bg-gray-900',
        className
      )}
    >
      {/* 头部工具栏 */}
      {(title || filename || language) && (
        <div className="flex items-center justify-between px-4 py-2 bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700">
          <div className="flex items-center space-x-3">
            {(title || filename) && (
              <span className="text-sm font-medium text-gray-900 dark:text-gray-100">
                {title || filename}
              </span>
            )}
            {language && (
              <Badge className={cn('text-xs', getLanguageColor(language))}>
                {displayLanguage.toUpperCase()}
              </Badge>
            )}
          </div>

          <div className="flex items-center space-x-1">
            {allowRun && (
              <Button
                size="sm"
                variant="ghost"
                onClick={runCode}
                className="h-7 px-2 text-xs"
              >
                <Play className="h-3 w-3 mr-1" />
                运行
              </Button>
            )}

            <Button
              size="sm"
              variant="ghost"
              onClick={() => setShowPreview(!showPreview)}
              className="h-7 px-2 text-xs"
            >
              {showPreview ? (
                <EyeOff className="h-3 w-3" />
              ) : (
                <Eye className="h-3 w-3" />
              )}
            </Button>

            <Button
              size="sm"
              variant="ghost"
              onClick={() => setIsExpanded(!isExpanded)}
              className="h-7 px-2 text-xs"
            >
              {isExpanded ? (
                <Minimize2 className="h-3 w-3" />
              ) : (
                <Maximize2 className="h-3 w-3" />
              )}
            </Button>

            {allowDownload && (
              <Button
                size="sm"
                variant="ghost"
                onClick={downloadCode}
                className="h-7 px-2 text-xs"
              >
                <Download className="h-3 w-3" />
              </Button>
            )}

            {allowCopy && (
              <CopyButton
                text={code}
                size="sm"
                variant="ghost"
                className="h-7 px-2 text-xs"
                toastMessage="代码已复制到剪贴板"
              />
            )}
          </div>
        </div>
      )}

      {/* 代码内容 */}
      <div
        className="relative overflow-auto"
        style={{ maxHeight: isExpanded ? 'none' : maxHeight }}
      >
        <pre
          ref={codeRef}
          className="p-4 text-sm font-mono leading-relaxed text-gray-800 dark:text-gray-200 bg-white dark:bg-gray-950"
        >
          {showLineNumbers ? (
            <div className="flex">
              {/* 行号 */}
              <div className="select-none text-gray-400 dark:text-gray-600 text-right pr-4 border-r border-gray-200 dark:border-gray-700 mr-4">
                {lines.map((_, index) => {
                  const lineNumber = index + 1;
                  const isHighlighted = highlightLines.includes(lineNumber);

                  return (
                    <div
                      key={index}
                      className={cn(
                        'leading-relaxed',
                        isHighlighted &&
                          'bg-yellow-100 dark:bg-yellow-900/30 -mx-1 px-1'
                      )}
                    >
                      {lineNumber}
                    </div>
                  );
                })}
              </div>

              {/* 代码内容 */}
              <div className="flex-1">
                {highlightedLines.map((line, index) => {
                  const lineNumber = index + 1;
                  const isHighlighted = highlightLines.includes(lineNumber);

                  return (
                    <div
                      key={index}
                      className={cn(
                        'leading-relaxed',
                        isHighlighted &&
                          'bg-yellow-100 dark:bg-yellow-900/30 -mx-4 px-4'
                      )}
                      dangerouslySetInnerHTML={{ __html: line || '&nbsp;' }}
                    />
                  );
                })}
              </div>
            </div>
          ) : (
            <div dangerouslySetInnerHTML={{ __html: highlightedCode }} />
          )}
        </pre>
      </div>
    </div>
  );
}

/**
 * 内联代码组件
 */
interface InlineCodeProps {
  children: React.ReactNode;
  className?: string;
}

export function InlineCode({ children, className }: InlineCodeProps) {
  return (
    <code
      className={cn(
        'px-1.5 py-0.5 bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded text-sm font-mono',
        className
      )}
    >
      {children}
    </code>
  );
}

/**
 * 代码组示例
 */
interface CodeGroupProps {
  children: React.ReactNode;
  className?: string;
}

export function CodeGroup({ children, className }: CodeGroupProps) {
  return <div className={cn('space-y-4', className)}>{children}</div>;
}
